﻿Option Strict On

''' <summary>
''' Performs the sorting of items in a ListView control displaying elements of a FileList object when the Sort() method is called.
''' Implements the IComparer interface.
''' </summary>
Public Class FileListViewSorter
    Implements System.Collections.IComparer

    Private Const CLM_NUMERICAL_COMPARE As Integer = 3

    Private iColumnToSort As Integer
    Private oSortOrder As SortOrder

    ''' <summary>
    ''' Creates a new FileListViewSorter object.
    ''' </summary>
    ''' <param name="sortedColumn">Optional specification of a column that is already sorted at time of list population.</param>
    ''' <param name="sortedOrder">Optional specification of the order in which the previously specified column is sorted.</param>
    Public Sub New(Optional ByVal sortedColumn As Integer = 0, Optional ByVal sortedOrder As SortOrder = SortOrder.None)

        iColumnToSort = sortedColumn
        oSortOrder = sortedOrder    'benefits of using imports windows.forms?

    End Sub

    ''' <summary>
    ''' Compares two ListViewItems and returns the result.
    ''' </summary>
    ''' <param name="x">The first ListViewItem to compare.</param>
    ''' <param name="y">The second ListViewItem to compare.</param>
    ''' <returns>Value indicating whether x is less than, equal to, or greater than y.</returns>
    ''' <remarks>Investigate possibility of implementing IComparer for sorting numerically</remarks>
    Public Function Compare(x As Object, y As Object) As Integer Implements System.Collections.IComparer.Compare

        Dim iComparisonResult As Integer
        Dim sItemX As String = DirectCast(x, ListViewItem).SubItems(iColumnToSort).Text
        Dim sItemY As String = DirectCast(y, ListViewItem).SubItems(iColumnToSort).Text

        If iColumnToSort = CLM_NUMERICAL_COMPARE Then
            Select Case CSng(Left(sItemX, sItemX.Length - 3))
                Case Is > CSng(Left(sItemY, sItemY.Length - 3))
                    iComparisonResult = 1
                Case Is < CSng(Left(sItemY, sItemY.Length - 3))
                    iComparisonResult = -1
                Case Is = CSng(Left(sItemY, sItemY.Length - 3))
                    iComparisonResult = 0
            End Select
        Else
            iComparisonResult = String.Compare(sItemX, sItemY, StringComparison.CurrentCultureIgnoreCase)
        End If

        Select Case oSortOrder
            Case SortOrder.Ascending
                Return iComparisonResult
            Case SortOrder.Descending
                Return (-iComparisonResult)
            Case Else
                Return 0
        End Select

    End Function

    ''' <summary>
    ''' Gets/sets the ListView column to be sorted.
    ''' </summary>
    ''' <returns>Value indicating the column to be sorted.</returns>
    Public Property SortColumn() As Integer

        Set(ByVal value As Integer)
            iColumnToSort = value
        End Set

        Get
            Return iColumnToSort
        End Get

    End Property

    ''' <summary>
    ''' Gets/sets the order by which to sort the ListView column.
    ''' </summary>
    ''' <returns>SortOrder object indicating the order by which to sort the ListView column.</returns>
    Public Property Order() As SortOrder

        Set(ByVal value As SortOrder)
            oSortOrder = value
        End Set

        Get
            Return oSortOrder
        End Get

    End Property

End Class
